package com.zhentao.datacontrol.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.datacontrol.domain.dto.RuleGroupDTO;
import com.zhentao.datacontrol.domain.entity.RuleGroup;
import com.zhentao.datacontrol.mapper.RuleGroupMapper;
import com.zhentao.datacontrol.service.RuleGroupService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup> implements RuleGroupService {

    @Autowired
    private RuleGroupMapper ruleGroupMapper;

    @Override
    public List<RuleGroupDTO> getGroupTree() {
        try {
            List<RuleGroup> allGroups = ruleGroupMapper.selectTreeList();
            return buildTree(allGroups);
        } catch (Exception e) {
            // 如果表不存在或查询失败，返回空列表
            if (e.getMessage() != null &&
                (e.getMessage().contains("doesn't exist") ||
                 e.getMessage().contains("Table") ||
                 e.getMessage().contains("table"))) {
                return new ArrayList<>();
            }
            // 其他异常继续抛出
            throw new RuntimeException("获取分组树失败: " + e.getMessage(), e);
        }
    }

    @Override
    public List<RuleGroupDTO> getTopLevelGroups() {
        try {
            List<RuleGroup> topGroups = ruleGroupMapper.selectTopLevel();
            return topGroups.stream().map(this::convertToDTO).collect(Collectors.toList());
        } catch (Exception e) {
            if (e.getMessage() != null &&
                (e.getMessage().contains("doesn't exist") ||
                 e.getMessage().contains("Table") ||
                 e.getMessage().contains("table"))) {
                return new ArrayList<>();
            }
            throw new RuntimeException("获取顶级分组失败: " + e.getMessage(), e);
        }
    }

    @Override
    public List<RuleGroupDTO> getChildGroups(Long parentId) {
        try {
            List<RuleGroup> childGroups = ruleGroupMapper.selectByParentId(parentId);
            return childGroups.stream().map(this::convertToDTO).collect(Collectors.toList());
        } catch (Exception e) {
            if (e.getMessage() != null &&
                (e.getMessage().contains("doesn't exist") ||
                 e.getMessage().contains("Table") ||
                 e.getMessage().contains("table"))) {
                return new ArrayList<>();
            }
            throw new RuntimeException("获取子分组失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional
    public Long createGroup(RuleGroupDTO groupDTO) {
        try {
            // 检查名称是否重复
            if (checkGroupNameExists(groupDTO.getGroupName(), groupDTO.getParentId(), null)) {
                throw new RuntimeException("分组名称已存在");
            }

            RuleGroup group = new RuleGroup();
            BeanUtils.copyProperties(groupDTO, group);

            // 设置排序号
            if (group.getSortOrder() == null) {
                group.setSortOrder(ruleGroupMapper.getNextSortOrder(group.getParentId()));
            }

            // 设置分组层级
            if (group.getParentId() == null) {
                group.setGroupLevel(1);
            } else {
                group.setGroupLevel(2);
            }

            group.setCreatedTime(LocalDateTime.now());
            group.setUpdatedTime(LocalDateTime.now());

            ruleGroupMapper.insert(group);
            return group.getId();
        } catch (Exception e) {
            if (e.getMessage().contains("doesn't exist")) {
                throw new RuntimeException("数据库表不存在，请先创建dc_rule_group表");
            }
            throw new RuntimeException("创建分组失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean updateGroup(RuleGroupDTO groupDTO) {
        // 检查名称是否重复
        if (checkGroupNameExists(groupDTO.getGroupName(), groupDTO.getParentId(), groupDTO.getId())) {
            throw new RuntimeException("分组名称已存在");
        }

        RuleGroup group = ruleGroupMapper.selectById(groupDTO.getId());
        if (group == null) {
            throw new RuntimeException("分组不存在");
        }

        BeanUtils.copyProperties(groupDTO, group);
        group.setUpdatedTime(LocalDateTime.now());

        return ruleGroupMapper.updateById(group) > 0;
    }

    @Override
    @Transactional
    public boolean deleteGroup(Long id) {
        // 检查是否有子分组
        List<RuleGroup> children = ruleGroupMapper.selectByParentId(id);
        if (!children.isEmpty()) {
            throw new RuntimeException("存在子分组，无法删除");
        }

        // TODO: 检查是否有关联的规则

        // 逻辑删除
        RuleGroup group = new RuleGroup();
        group.setId(id);
        group.setIsDelete(1);
        group.setUpdatedTime(LocalDateTime.now());

        return ruleGroupMapper.updateById(group) > 0;
    }

    @Override
    @Transactional
    public boolean moveGroup(Long id, Long targetParentId, Integer targetSortOrder) {
        RuleGroup group = ruleGroupMapper.selectById(id);
        if (group == null) {
            throw new RuntimeException("分组不存在");
        }

        group.setParentId(targetParentId);
        group.setSortOrder(targetSortOrder);
        group.setGroupLevel(targetParentId == null ? 1 : 2);
        group.setUpdatedTime(LocalDateTime.now());

        return ruleGroupMapper.updateById(group) > 0;
    }

    @Override
    public boolean checkGroupNameExists(String groupName, Long parentId, Long excludeId) {
        return ruleGroupMapper.checkGroupNameExists(groupName, parentId, excludeId) > 0;
    }

    @Override
    public RuleGroupDTO getGroupDetail(Long id) {
        RuleGroup group = ruleGroupMapper.selectById(id);
        if (group == null) {
            return null;
        }
        return convertToDTO(group);
    }

    @Override
    @Transactional
    public boolean updateSortOrders(List<Long> ids, List<Integer> sortOrders) {
        if (ids.size() != sortOrders.size()) {
            throw new RuntimeException("参数长度不匹配");
        }

        for (int i = 0; i < ids.size(); i++) {
            ruleGroupMapper.updateSortOrder(ids.get(i), sortOrders.get(i));
        }

        return true;
    }

    /**
     * 构建树形结构
     */
    private List<RuleGroupDTO> buildTree(List<RuleGroup> allGroups) {
        Map<Long, List<RuleGroup>> groupMap = allGroups.stream()
                .collect(Collectors.groupingBy(group -> group.getParentId() == null ? 0L : group.getParentId()));

        List<RuleGroupDTO> rootGroups = new ArrayList<>();

        // 处理顶级分组
        List<RuleGroup> topGroups = groupMap.get(0L);
        if (topGroups != null) {
            for (RuleGroup group : topGroups) {
                RuleGroupDTO dto = convertToDTO(group);
                dto.setChildren(buildChildren(group.getId(), groupMap));
                rootGroups.add(dto);
            }
        }

        return rootGroups;
    }

    /**
     * 构建子节点
     */
    private List<RuleGroupDTO> buildChildren(Long parentId, Map<Long, List<RuleGroup>> groupMap) {
        List<RuleGroup> children = groupMap.get(parentId);
        if (children == null || children.isEmpty()) {
            return new ArrayList<>();
        }

        return children.stream().map(child -> {
            RuleGroupDTO dto = convertToDTO(child);
            dto.setChildren(buildChildren(child.getId(), groupMap));
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 实体转DTO
     */
    private RuleGroupDTO convertToDTO(RuleGroup group) {
        RuleGroupDTO dto = new RuleGroupDTO();
        BeanUtils.copyProperties(group, dto);
        return dto;
    }
}
